package network

import (
	"errors"
	"fmt"
	"go-iot/app/common/boot"
	"go-iot/app/models"
	"go-iot/app/iot/network"
	"go-iot/app/common/mysql"
	"gorm.io/gorm"
	"time"
	"go-iot/app/common/logger"
)

func init() {
    boot.AddStartLinstener(func() {
        var count int64
        err := mysql.DB.Model(&models.Network{}).Count(&count).Error
        if err == nil && count == 0 {
			for i := 0; i < 10; i++ {
				AddNetWork(&models.Network{Id: int64(i + 1), Port: int32(9010 + i), State: models.Stop, ProductId: ""})
			}
			logger.Infof("init networks")
		}
    })
}

// 分页查询设备
func PageNetwork(page *models.PageQuery) (*models.PageResult[models.Network], error) {
    var networks []models.Network
    var total int64

    // 构建查询
	query := mysql.DB.Model(&models.Network{})
    // 添加条件过滤
    for _, condition := range page.Condition {
        query = query.Where(condition.Key+" = ?", condition.Value)
    }

    // 获取总数
    if err := query.Count(&total).Error; err != nil {
        return nil, fmt.Errorf("查询总数失败: %v", err)
    }

    // 执行分页查询
    if err := query.Order("create_time desc, id desc").
        Offset(page.PageOffset()).
        Limit(page.PageSize).
        Find(&networks).Error; err != nil {
        return nil, fmt.Errorf("分页查询失败: %v", err)
    }

    result := models.PageUtil(total, page.PageNum, page.PageSize, networks)
    return &result, nil
}


func AddNetWork(ob *models.Network) error {
	if !network.IsNetClientType(ob.Type) {
		if ob.Port <= 1024 || ob.Port > 65535 {
			return errors.New("invalid port number")
		}
		rs, err := GetNetworkByPort(ob.Port)
		if err != nil {
			return err
		}
		if rs != nil && rs.Id > 0 {
			return fmt.Errorf("端口[%d]已被使用", ob.Port)
		}
	}
	if len(ob.ProductId) > 0 {
		nw, err := GetByProductId(ob.ProductId)
		if err != nil {
			return err
		}
		if nw != nil {
			return fmt.Errorf("网络配置已被产品[%s]管理", ob.ProductId)
		}
	}
    ob.State = models.Stop
    ob.CreateTime = time.Now()
    
    if err := mysql.DB.Create(ob).Error; err != nil {
        return fmt.Errorf("创建网络配置失败: %v", err)
    }
    
    return nil
}


func UpdateNetwork(ob *models.Network) error {
    // 验证端口号
    if ob.Port > 0 {
        if ob.Port <= 1024 || ob.Port > 65535 {
            return errors.New("端口号必须大于1024且小于65535")
        }
    }

    network, err := GetNetwork(ob.Id)
    if err != nil {
        return errors.New(err.Error())
    }

    if network.AllowView == 1 {
		return errors.New("禁止编辑")
	}

    // 构建更新字段
    updates := make(map[string]interface{})
    if ob.Port > 0 {
        updates["port"] = ob.Port
    }
    if len(ob.ProductId) > 0 {
        updates["product_id"] = ob.ProductId
    }
    if len(ob.Type) > 0 {
        updates["type"] = ob.Type
    }
    if len(ob.Name) > 0 {
        updates["name"] = ob.Name
    }
    if len(ob.Configuration) > 0 {
        updates["configuration"] = ob.Configuration
    }
    if len(ob.State) > 0 {
        updates["state"] = ob.State
    }
    if len(ob.CertBase64) > 0 {
        updates["cert_base64"] = ob.CertBase64
    }
    if len(ob.KeyBase64) > 0 {
        updates["key_base64"] = ob.KeyBase64
    }
    
    // 如果没有需要更新的字段，直接返回
    if len(updates) == 0 {
        return nil
    }
    
    result := mysql.DB.Model(&network).Updates(updates)
    if result.Error != nil {
		return fmt.Errorf("更新网络配置失败: %v", result.Error)
	}
    
    return nil
}

func DeleteNetwork(ob *models.Network) error {

    network, err := GetNetwork(ob.Id)
    if err != nil {
        return errors.New(err.Error())
    }

    if network.AllowView == 1 {
		return errors.New("禁止删除")
	}

    if err := mysql.DB.Delete(&network).Error; err != nil {
		return fmt.Errorf("删除网络配置失败: %v", err)
	}

    return nil
}

func GetNetwork(id int64) (models.Network, error) {
    var network models.Network
    
    result := mysql.DB.First(&network, id)
    if result.Error != nil {
        if result.Error == gorm.ErrRecordNotFound {
            return models.Network{}, nil
        }
        return models.Network{}, fmt.Errorf("查询网络配置失败: %v", result.Error)
    }

    if network.AllowView == 1 {
		network.Configuration = ""
	}
    
    return network, nil
}

func GetByProductId(productId string) (*models.Network, error) {
    var network models.Network
    
    result := mysql.DB.Where("product_id = ?", productId).First(&network)
    if result.Error != nil {
        if result.Error == gorm.ErrRecordNotFound {
            return nil, nil
        }
        return nil, fmt.Errorf("查询产品网络配置失败: %v", result.Error)
    }

    if network.AllowView == 1 {
		network.Configuration = ""
	}
    
    return &network, nil
}

// 查询端口是否被使用
func GetNetworkByPort(port int32) (*models.Network, error) {
    var network models.Network
    
    result := mysql.DB.Where("port = ?", port).First(&network)
    if result.Error != nil {
        if result.Error == gorm.ErrRecordNotFound {
            return nil, nil
        }
        return nil, fmt.Errorf("查询网络配置失败: %v", result.Error)
    }
    
    return &network, nil
}


func GetUnuseNetwork() (*models.Network, error) {
    var network models.Network
    
    result := mysql.DB.Where("product_id = ?", "").
        Order("port").
        First(&network)
    
    if result.Error != nil {
        if result.Error == gorm.ErrRecordNotFound {
            return nil, errors.New("没有空闲的端口可以使用")
        }
        return nil, fmt.Errorf("查询空闲网络配置失败: %v", result.Error)
    }
    
    return &network, nil
}

// 绑定网络服务与产品
func BindNetworkProduct(productId, networkType string) (*models.Network, error) {
    if network.IsNetClientType(networkType) {
        var nw models.Network
        result := mysql.DB.Where("product_id = ?", productId).First(&nw)
        
        if result.Error == gorm.ErrRecordNotFound {
            err := AddNetWork(&models.Network{
                ProductId: productId,
                Type:     networkType,
                State:    models.Stop,
            })
            if err != nil {
                return nil, err
            }
            // 重新查询新创建的网络配置
            if err := mysql.DB.Where("product_id = ?", productId).First(&nw).Error; err != nil {
                return nil, fmt.Errorf("查询网络配置失败: %v", err)
            }
        } else if result.Error != nil {
            return nil, fmt.Errorf("查询网络配置失败: %v", result.Error)
        }
        
        return &nw, nil
    } else {
        nw, err := GetUnuseNetwork()
        if err != nil {
            return nil, err
        }
        
        // 更新网络配置
        updates := map[string]interface{}{
            "product_id": productId,
            "type":      networkType,
        }
        
        if err := mysql.DB.Model(nw).Updates(updates).Error; err != nil {
            return nil, fmt.Errorf("更新网络配置失败: %v", err)
        }
        
        return nw, nil
    }
}

// 解绑网络服务与产品
func UnbindNetworkProduct(productId string) error {
    nw, err := GetByProductId(productId)
    if err != nil {
        return err
    }
    if nw != nil {
        if network.IsNetClientType(nw.Type) {
            err := DeleteNetwork(nw)
            return err
        } else {
            updates := map[string]interface{}{
                "product_id":    "",
                "type":         "",
                "configuration": "",
                "state":        "stop",
            }
            
            if err := mysql.DB.Model(nw).Updates(updates).Error; err != nil {
                return fmt.Errorf("更新网络配置失败: %v", err)
            }
        }
    }
    return nil
}

// 查询所有网络配置
func AllNetwork() ([]models.Network, error) {
    var networks []models.Network
    
    if err := mysql.DB.Order("create_time desc, id desc").Find(&networks).Error; err != nil {
        return nil, fmt.Errorf("查询网络配置失败: %v", err)
    }
    
    return networks, nil
}
